package Concurrency1.Chapter01_Base;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * 功能说明：多线程并发下的可见性问题及解决
 * 试验:
 * 测试逻辑1, 通过变量作为开关, 控制另一个线程的执行
 *
 * 测试逻辑2,
 * 条件1: 在没有volatile的前提下:
 * -server模式, -client模式 : 子线程都见不到变量被修改
 * 条件2: volatile开启后
 * 子线程正常见到修改
 *
 * 开发人员：@author MaLi
 */
public class C04_Visibility {
    private /*volatile*/ static boolean run = true; //测试volatile是否开启时, 数据的修改是否实时对数据可见.

    public static void main(String[] args) throws IOException {
        //testCase1();
        new Thread(() -> {
            while(run); //默认在这里循环执行, 不会执行下一句.
            System.out.println(Thread.currentThread().getName()+" is Running"); //一旦执行, 就说明run为false了
        }, "Thread_wait").start();

        //主线程
        try {
            TimeUnit.SECONDS.sleep(3); //主线程休眠3秒
            run = false;
            System.out.println("主线程, 改变run为false");
            TimeUnit.SECONDS.sleep(10);//等待10秒后程序自动退出
            System.out.println("主线程结束");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private static void testCase1() throws IOException {
        new Thread(() -> {
            while (run) {
                //只要运行状态下, 就输出信息
                System.out.println(Thread.currentThread().getName() + " is runging: " + System.currentTimeMillis());

            }
        }, "Thread_Controlled").start();

        try {
            //主线程在休眠5秒后, 把run置为false, 测试看自定义线程是否会马上停止打印
            TimeUnit.SECONDS.sleep(1);
            run = false;
            System.err.println(Thread.currentThread().getName() + "关闭开关" + System.currentTimeMillis());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.in.read();
    }
}
